package cn.com.acca.ma.dao.impl;

import cn.com.acca.ma.hibernate.impl.GetMACDGoldCrossSuccessRateWorkImpl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.com.acca.ma.pojo.SuccessRateOrPercentagePojo;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

import cn.com.acca.ma.dao.ModelMACDGoldCrossDao;
import cn.com.acca.ma.hibernate.util.HibernateUtil;
import cn.com.acca.ma.model.ModelMACDGoldCross;

public class ModelMACDGoldCrossDaoImpl extends BaseDaoImpl<ModelMACDGoldCross> implements ModelMACDGoldCrossDao {

	public ModelMACDGoldCrossDaoImpl() {
		super();
	}

	/*********************************************************************************************************************
	 * 
	 * 												按日期计算数据
	 * 
	 *********************************************************************************************************************/
	/**
	 * 使用日线级别MACD金叉模型算法，根据endDate日期，向表MDL_MACD_GOLD_CROSS插入数据
	 * @param multithreading
	 * @param endDate
	 */
	public void writeModelMACDGoldCrossIncr(boolean multithreading, String endDate){
		logger.info("write model MACD gold cross incrementally begin");

		Session newSession = null;
		SQLQuery query;
		if (multithreading) {
			newSession = HibernateUtil.newSession();
			newSession.beginTransaction();
			query = newSession.createSQLQuery("{call PKG_MODEL_RECORD.CAL_MDL_MACD_GOLD_CROSS_INCR(?)}");
		} else {
			session= HibernateUtil.currentSession();
			session.beginTransaction();
			query = session.createSQLQuery("{call PKG_MODEL_RECORD.CAL_MDL_MACD_GOLD_CROSS_INCR(?)}");
		}

		query.setString(0, endDate);
		query.executeUpdate();

		if (multithreading) {
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session.getTransaction().commit();
			session.close();
		}

		logger.info("write model MACD gold cross incrementally finish");
	}
	
	/*********************************************************************************************************************
	 * 
	 * 												   	创建图表
	 * 
	 *********************************************************************************************************************/
	/**
	 * 从表MDL_MACD_GOLD_CROSS中获取PROFIT_LOSS大于零的记录
	 * @param multithreading
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<ModelMACDGoldCross> getProfitMACDGoldCross(boolean multithreading){
		logger.info("method getProfitMACDGoldCross begin");
		
		String hql = "select t from ModelMACDGoldCross t where t.profitLoss>0 order by buyDate asc";

		Session newSession = null;
		Query query;
		if (multithreading) {
			newSession = HibernateUtil.newSession();
			newSession.beginTransaction();
			query = newSession.createQuery(hql);
		} else {
			session = HibernateUtil.currentSession();
			session.beginTransaction();
			query = session.createQuery(hql);
		}

		List<ModelMACDGoldCross> list = query.list();

		if (multithreading) {
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session.getTransaction().commit();
			session.close();
		}

		logger.info("method getProfitMACDGoldCross finish");
		return list;
	}

	/**
	 * 从表MDL_MACD_GOLD_CROSS中获取PROFIT_LOSS小于零的记录
	 * @param multithreading
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List getLossMACDGoldCross(boolean multithreading, String beginDate, String endDate){
		logger.info("method getLossMACDGoldCross begin");
		
		String hql = "select t.profitLoss,(t.buyDif+t.buyDea)/2 from ModelMACDGoldCross t where t.buyDate between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd')";

		Session newSession = null;
		Query query;
		if (multithreading) {
			newSession = HibernateUtil.newSession();
			newSession.beginTransaction();
			query = newSession.createQuery(hql);
		} else {
			session = HibernateUtil.currentSession();
			session.beginTransaction();
			query = session.createQuery(hql);
		}

		query.setParameter(0, beginDate);
		query.setParameter(1, endDate);
		List<ModelMACDGoldCross> list = query.list();

		if (multithreading) {
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session.getTransaction().commit();
			session.close();
		}
		
		logger.info("method getLossMACDGoldCross finish");
		return list;
	}

	/**
	 * 根据beginDate和endDate，查找macd金叉算法成功时，dif和dea的分布。profitLoss为true时表示盈利，为true时表示亏损
	 * @param multithreading
	 * @param beginDate
	 * @param endDate
	 * @param profitLoss
	 * @return
	 */
	public List getMACDGoldCrossSuccessDifDea(boolean multithreading, String beginDate, String endDate, boolean profitLoss){
		logger.info("根据beginDate【" + beginDate + "】和endDate【" + endDate + "】，"
			+ "查找macd金叉算法成功时，dif和dea的分布");

		String hql = "select (t.buyDif + t.buyDea)/2, t.buyDate from ModelMACDGoldCross t "
			+ "where t.profitLoss";
		if (profitLoss){
			hql += ">0 ";
		} else {
			hql += "<0 ";
		}
		hql += "and t.buyDate>=to_date(?, 'yyyy-mm-dd') ";
		hql += "and t.sellDate<=to_date(?, 'yyyy-mm-dd')";

		Session newSession = null;
		Query query;
		if (multithreading) {
			newSession = HibernateUtil.newSession();
			newSession.beginTransaction();
			query = newSession.createQuery(hql);
		} else {
			session = HibernateUtil.currentSession();
			session.beginTransaction();
			query = session.createQuery(hql);
		}

		query.setParameter(0, beginDate);
		query.setParameter(1, endDate);
		List list = query.list();

		if (multithreading) {
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session.getTransaction().commit();
			session.close();
		}

		logger.info("根据beginDate【" + beginDate + "】和endDate【" + endDate + "】，"
			+ "查找macd金叉算法成功时，dif和dea的分布完成");
		return list;
	}

	/**
	 * 获取MACD金叉算法在开始时间到结束时间内成功率的数据
	 * @param multithreading
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public List<SuccessRateOrPercentagePojo> getMACDGoldCrossSuccessRate(boolean multithreading, final String beginDate, final String endDate, Integer dateNumber){
		logger.info("获取开始时间【" + beginDate + "】至【" + endDate + "】内，最近【" + dateNumber + "】天，MACD金叉的成功率");
        
        final List<SuccessRateOrPercentagePojo> list=new ArrayList<SuccessRateOrPercentagePojo>();

        if (multithreading) {
        	Session newSession = HibernateUtil.newSession();
        	newSession.beginTransaction();
			newSession.doWork(new GetMACDGoldCrossSuccessRateWorkImpl(beginDate, endDate, dateNumber, list));
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session=HibernateUtil.currentSession();
			session.beginTransaction();
			session.doWork(new GetMACDGoldCrossSuccessRateWorkImpl(beginDate, endDate, dateNumber, list));
			session.getTransaction().commit();
			session.close();
		}

        logger.info("获取一段时间内，最近" + dateNumber + "天，MACD金叉的成功率完成");
        return list;
	}

	/**
	 * 获取MACD金叉算法在开始时间到结束时间内，金叉股票的百分比
	 * @param multithreading
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	public List<SuccessRateOrPercentagePojo> getMACDGoldCrossPercentage(boolean multithreading, final String beginDate, final String endDate){
		logger.info("开始获取MACD金叉算法在开始时间【" + beginDate + "】到结束时间【" + endDate + "】内，金叉股票的百分比");

//		String hql = "select new cn.com.acca.ma.pojo.SuccessRateOrPercentagePojo(t.date as transactionDate, " +
//				"(select count(*) from StockTransactionData t1 where t1.date=t.date " +
//				"and t1.dif>t1.dea)/ " +
//				"(select count(*) from StockTransactionData t1 where t1.date=t.date)*100 as successRateOrPercentage) " +
//				"from StockTransactionData t " +
//				"where t.date between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd') " +
//				"group by t.date order by t.date asc";

		String hql = "select t.date_ transactionDate, " +
				"(select count(*) from stock_transaction_data_all t1 where t1.date_=t.date_ " +
				"and t1.dif>t1.dea)/ " +
				"(select count(*) from stock_transaction_data_all t1 where t1.date_=t.date_)*100 successRateOrPercentage " +
				"from stock_transaction_data_all t " +
				"where t.date_ between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd') " +
				"group by t.date_ order by t.date_ asc";

		Session newSession = null;
		Query query;
		if (multithreading) {
			newSession = HibernateUtil.newSession();
			newSession.beginTransaction();
			query = newSession.createSQLQuery(hql).addEntity(SuccessRateOrPercentagePojo.class);
		} else {
			session = HibernateUtil.currentSession();
			session.beginTransaction();
			query = session.createSQLQuery(hql).addEntity(SuccessRateOrPercentagePojo.class);
		}

		query.setParameter(0, beginDate);
		query.setParameter(1, endDate);
		List<SuccessRateOrPercentagePojo> list = query.list();

		if (multithreading) {
			newSession.getTransaction().commit();
			HibernateUtil.closeNewSessionFactory(newSession);
		} else {
			session.getTransaction().commit();
			session.close();
		}

		return list;
	}
	
	/*********************************************************************************************************************
	 * 
	 * 												计算全部数据
	 * 
	 *********************************************************************************************************************/
	/**
	 * 使用日线级别MACD金叉模型算法，向表MDL_MACD_GOLD_CROSS插入数据
	 */
	public void writeModelMACDGoldCross() {
		logger.info("开始使用日线级别MACD金叉模型算法，向表MDL_MACD_GOLD_CROSS插入数据");
		
		session= HibernateUtil.currentSession();
		session.beginTransaction();
		SQLQuery query = session.createSQLQuery("{call PKG_MODEL_RECORD.CAL_MDL_MACD_GOLD_CROSS()}");
		query.executeUpdate();
		session.getTransaction().commit();
		session.close();
		
		logger.info("使用日线级别MACD金叉模型算法，向表MDL_MACD_GOLD_CROSS插入数据完成");
	}

	/*********************************************************************************************************************
	 * 
	 * 										增量备份表MDL_MACD_GOLD_CROSS
	 * 
	 *********************************************************************************************************************/
	/**
	 * 根据开始时间beginDate和结束时间endDate，从表MDL_MACD_GOLD_CROSS中获取SELL_DATE字段
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Date> getDateByCondition(String beginDate, String endDate){
		logger.info("根据开始时间【" + beginDate + "】和结束时间【" + endDate + "】，"
			+ "从表MDL_MACD_GOLD_CROSS中获取SELL_DATE字段");
		
		StringBuffer hql = new StringBuffer("select distinct t.sellDate from ModelMACDGoldCross t " +
				"where t.sellDate between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd')");
		session = HibernateUtil.currentSession();
		session.beginTransaction();
		Query query = session.createQuery(hql.toString());
		query.setParameter(0, beginDate);
		query.setParameter(1, endDate);
		List<Date> list = query.list();
		session.getTransaction().commit();
		session.close();
		
		return list;
	}
	
	/**
	 * 从表MDL_MACD_GOLD_CROSS中获取date日的所有ModelMACDGoldCross对象
	 * @param date
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<ModelMACDGoldCross> getModelMACDGoldCrossByDate(String date){
		logger.info("从表MDL_MACD_GOLD_CROSS中获取日期【" + date + "】的所有ModelMACDGoldCross对象");
		
		StringBuffer hql = new StringBuffer("select t from ModelMACDGoldCross t " +
				"where t.sellDate=to_date(?,'yyyy-mm-dd') order by t.sellDate asc");
		session = HibernateUtil.currentSession();
		session.beginTransaction();
		Query query = session.createQuery(hql.toString());
		query.setParameter(0, date);
		List<ModelMACDGoldCross> list=query.list();
		session.getTransaction().commit();
		session.close();
		
		return list;
	}
	
	/**
	 * 向表MDL_MACD_GOLD_CROSS中插入ModelMACDGoldCross对象
	 * @param modelMACDGoldCross
	 */
	public void save(ModelMACDGoldCross modelMACDGoldCross){
		logger.info("向表MDL_MACD_GOLD_CROSS中插入ModelMACDGoldCross对象");
		
		session = HibernateUtil.currentSession();
		session.beginTransaction();
		session.persist(modelMACDGoldCross);
		session.getTransaction().commit();
		session.close();
	}
}
